// 泛型
interface Ref<T> { value: T }
type MyObj = { name: string; getName: (name: string) => void }
let myObj: Ref<MyObj> = { value: { name: "张三", getName(name: string) {} } }

// 泛型的默认值
// 这里并未“使用了泛型”，只有在外部调用时，才算使用。这里是泛型中转，将泛型中转给类的属性
type DefaultObj = { usename: string, age: number }
class ArrayList<T=DefaultObj> {
  arr: Array<T>;  // 泛型中转
  index: number = 0;
  constructor() { this.arr = [] }
  add(ele: T) { this.arr[this.index++] = ele }
  get(index: number) { return this.arr[index] }
}
let arrList = new ArrayList()
arrList.add({ usename: "张三", age: 18 })

// extends泛型约束
class Order {
  orderName!: string
  orderId!: number
  static count: number
  getOrderName() {}
  static PrintOrder() {}
}
type OrderId = Order["orderId"]  // 获取类的某个属性的值的类型
let orderId: OrderId = 1101

type InstanceKeyOf<T extends object> = keyof T  // keyof，由对象的属性名组成的联合类型
type OrderProps = InstanceKeyOf<Order>
let orderName: OrderProps = 'orderName'

// 联合类型约束与嵌套约束，组成的复杂extends泛型约束
type ObjType = { name: string; age: number }
type KeysType<T extends object, K extends keyof T> = T[K]
let obj: KeysType<ObjType, 'name' | 'age'> = 10086
console.log('obj', obj)

// vue3 泛型约束实战
class ObjectRefImple<T extends object, K extends keyof T> {
  public readonly __v_isRef = true
  constructor(private readonly _object: T, private readonly _key: K) {}

  get value() { return this._object[this._key] }
  set value(newVal) { this._object[this._key] = newVal }
}
type ObjectType = { usename: string, age?: number }
let objRef = new ObjectRefImple<ObjectType, 'usename'>({ usename: "张三" }, 'usename')
console.log("objRef.value: ", objRef.value)

export {}
